﻿//------------------------------------------------------------------------------------------------- 
// <copyright file="WebPropertyInfo.cs" company="Collaboris">
// Copyright (c) Collaboris.  All rights reserved.
// </copyright>
// <summary>Sets one or Properties on a Web.</summary>
//-------------------------------------------------------------------------------------------------
namespace Collaboris.Saf.Actions.Wss.Web
{
    using Engine;

    using Microsoft.SharePoint;
    using SharePoint.Wss;
    using SharePoint.Wss.Attributes;
    using SharePoint.Wss.Webs;

    using Utils;

    [CollaborisClass(
            Title = "Set Web Property",
            ReleaseStatus = ReleaseStatus.Development,
            DisableDocumentation = true,
            ContactAuthorEmail = "Support@Collaboris.co.uk",
            Summary = "Summarise the Action so much that the Administrator can easily understand " +
                      "what it's actually doing. You may also want to supply a link " +
                      "to any Urls that are relevant, or also any other actions.",
            Remarks = "PUT A GENERAL REMARKS AND ALSO INFO ABOUT WHAT THE UNDO ACTUALLY DOES.",
          ClassGuid = "{156E17A5-A7BA-4e1f-8A48-1BC341A7C660}"
        )
    ]
    public class SetWebProperty : WSSActionBase<WebPropertyInfo>
    {
        #region Fields (1)

        /// <summary>
        /// Set up the Action Name 
        /// </summary>
        //private const string ActionName = "Collaboris.SharePoint.Actions.Wss.Web.SetWebProperty";
        private const string lastSiteMasterKey = "SetSiteMasterPageKey";
        private const string lastSystemMasterKey = "SetSystemMasterPageKey";
        #endregion Fields

        #region Constructors (1)

        /// <summary>
        /// Initializes a new instance of the <see cref="SetWebProperty"/> class.
        /// </summary>
        public SetWebProperty()
        {
            this.Scope = SPScope.Web;
        }

        #endregion Constructors

        #region Methods (1)

        /*
        /// <summary>
        /// Return the name of this Action
        /// </summary>
        /// <returns></returns>
        public override string Name
        {
            get
            {
                return ActionName;
            }
        }
        */ 

        #endregion Methods

        #region Protected Methods

        /// <summary>
        /// Will reset the webs Master Page back to its previous setting before the 
        /// Undo.
        /// </summary>
        /// <param name="context">
        /// </param>
        /// <param name="entity">
        /// The entity.
        /// </param>
        /// <returns>
        /// </returns>
        protected override ProcessStatus UndoAction(SafContext context, SharePoint.Wss.Webs.WebPropertyInfo entity)
        {
            this.Trace.TraceMethodStart("UndoAction");

            ValidationHelper.VerifyObjectArgument(context.Site, "context.Site");

            using (SPWeb web = SPWebHelper.GetWeb(context.Site, entity.SiteUrl))
            {
                this.UndoProperties(web);

                if (entity.ApplyToSubSites)
                {
                    this.RunUndoChildren(web);
                }
            }
            
            this.Trace.TraceMethodEnd("UndoAction");

            return ProcessStatus.Success;
        }

        /// <summary>
        /// Causes the Webs Master Page to be set with data defined in the 
        /// <see cref="SetSingleMasterPage"/> entity
        /// </summary>
        /// <param name="context">
        /// </param>
        /// <param name="entity">
        /// The entity.
        /// </param>
        /// <returns>
        /// </returns>
        protected override ProcessStatus DoAction(SafContext context, SharePoint.Wss.Webs.WebPropertyInfo entity)
        {
            this.Trace.TraceMethodStart("DoAction");

            ValidationHelper.VerifyObjectArgument(context.Site, "context.Site");

            using (SPWeb web = SPWebHelper.GetWeb(context.Site, entity.SiteUrl))
            {
                this.DoProperties(entity, web);

                if (entity.ApplyToSubSites)
                {
                    this.RunDoChildren(entity, web);
                }
            }

            this.Trace.TraceMethodEnd("DoAction");

            return ProcessStatus.Success;
        }

        #endregion

        #region Private Methods
       
        /// <summary>
        /// Runs the undo children.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="web">The web.</param>
        private void RunUndoChildren(SPWeb web)
        {
            this.Trace.TraceMethodStart("RunUndoChildren()");
            foreach (SPWeb subWeb in web.Webs)
            {
                using (subWeb)
                {
                    this.UndoProperties(subWeb);
                    this.RunUndoChildren(subWeb);
                }
            }
            this.Trace.TraceMethodEnd("RunUndoChildren()");
        }

        /// <summary>
        /// Runs the do children.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="web">The web.</param>
        private void RunDoChildren(SharePoint.Wss.Webs.WebPropertyInfo entity, SPWeb web)
        {
            this.Trace.TraceMethodStart("RunDoChildren()");
            
            foreach (SPWeb subWeb in web.Webs)
            {
                using (subWeb)
                {
                    this.DoProperties(entity, subWeb);
                    this.RunDoChildren(entity, subWeb);
                }
            }

            this.Trace.TraceMethodEnd("RunDoChildren()");
        }

        /// <summary>
        /// Attempts to undo the properties for the current web.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="web">The web.</param>
        private void UndoProperties(SPWeb web)
        {
            this.Trace.TraceMethodStart("UndoProperties()");

            this.Trace.TraceVerbose("Attempting to undo the properties for this web '{0}'", web.Url);
            SharePoint.Wss.Webs.WebPropertyInfo oldVals = this.GetProperty<SharePoint.Wss.Webs.WebPropertyInfo>(web, "WebPropertyInfo");

            if (oldVals != null)
            {
                // lets cause and update with the old Values.
                SPWebHelper.UpdateProperties(web, oldVals);
            }
            else 
            {
                this.Trace.TraceWarning("Cannot load previous web properties from this web '{0}'", web.Url);
            }
            
            this.Trace.TraceMethodEnd("UndoProperties()");        
        }

        /// <summary>
        /// Updates the current Web with the properties passed in from the 
        /// entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="web">The web.</param>
        private void DoProperties(SharePoint.Wss.Webs.WebPropertyInfo entity, SPWeb web)
        {
            this.Trace.TraceMethodStart("DoProperties()");

            this.Trace.TraceVerbose("Attempting to set the properties on this web '{0}'", web.Url);

            SharePoint.Wss.Webs.WebPropertyInfo oldVals = SPWebHelper.UpdateProperties(web, entity);
            
            //now lets write the old Values back!
            this.SaveProperty<SharePoint.Wss.Webs.WebPropertyInfo>(web, "WebPropertyInfo", oldVals);

            this.Trace.TraceMethodEnd("DoProperties()");
        }

        #endregion
    }
}